{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "from skimage import io, filters, measure, segmentation, morphology, color\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd\n",
    "import joblib\n",
    "from pathlib2 import Path\n",
    "import warnings\n",
    "\n",
    "# 忽略警告\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "# 测量参数名称\n",
    "region_props = ['area', 'convex_area', 'bbox_area', 'filled_area', 'major_axis_length', 'minor_axis_length', 'moments_hu',\n",
    "                'eccentricity', 'equivalent_diameter', 'extent', 'feret_diameter_max', 'perimeter', 'solidity', 'perimeter_crofton',\n",
    "                'orientation', 'inertia_tensor_eigvals', 'bbox', 'centroid', 'image', 'label']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "def process_image(image_path):\n",
    "    # 读取图像\n",
    "    image = io.imread(image_path)\n",
    "    \n",
    "    # 转换为灰度图像\n",
    "    gray = color.rgb2gray(image)\n",
    "    \n",
    "    # 二值化\n",
    "    bw = gray < (80/255)\n",
    "    bw = morphology.remove_small_objects(bw, min_size=25)\n",
    "    bw = segmentation.clear_border(bw)\n",
    "    image_new = bw.copy()\n",
    "\n",
    "    bw_label = measure.label(bw)\n",
    "    regions = measure.regionprops_table(bw_label, properties=region_props)\n",
    "    df = pd.DataFrame(regions)\n",
    "    return df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\1\\Konachan.com_-_368758_animal_anthropomorphism_azur_lane_barefoot_bird_blush_bow_dress_flowers_green_eyes_hat_instrument_loli_petals_piano_pink_hair_ribbons_twintails.jpg\n",
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\1\\Konachan.com_-_368772_azur_lane_blue_eyes_blush_boots_bow_braids_bunnygirl_collar_drink_food_gray_hair_headband_hoodie_leotard_logo_loli_red_eyes_shnva_skirt_tail_wink.jpg\n",
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\1\\Konachan.com_-_369211_anthropomorphism_azur_lane_breasts_building_butterfly_cleavage_haneru_japanese_clothes_kimono_logo_long_hair_night_purple_eyes_tree_white_hair.jpg\n",
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\1\\Konachan.com_-_369255_2girls_animal_atdan_azur_lane_barefoot_bird_brown_hair_cherry_blossoms_clouds_demon_flowers_horns_long_hair_purple_eyes_red_eyes_sky_tree_wink.jpg\n",
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\2\\Konachan.com_-_369454_blush_bow_breasts_building_city_cleavage_couch_drink_fang_gloves_gray_hair_headband_horns_jeze_leotard_night_pantyhose_red_eyes_red_hair_waitress.jpg\n",
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\2\\yande.re_1037327_ajitani_hifumi_angel_blue_archive_nijihashi_sora_pantyhose_seifuku_shimoe_koharu_shirasu_azusa_sweater_urawa_hanako_wings (1).jpg\n",
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\2\\yande.re_1088039_angel_animal_ears_asuma_toki_blue_archive_bunny_ears_bunny_girl_cameltoe_feet_hokori_sakuni_no_bra_thighhighs (1).jpg\n",
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\2\\yande.re_1120092_azur_lane_criin_haruna_(azur_lane)_japanese_clothes_manjuu_(azur_lane) (1).jpg\n",
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\3\\yande.re_1145612_breasts_ganyu_genshin_impact_horns_kimono_misako_nipples_no_bra_open_shirt (1).jpg\n",
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\3\\yande.re_1146418_animal_ears_atago_(azur_lane)_azur_lane_chyoel_maid_stockings_thighhighs (1).jpg\n",
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\3\\yande.re_1146838_ass_azur_lane_heels_manjuu_(azur_lane)_new_jersey_(azur_lane)_no_bra_pantyhose_shinano_(azur_lane)_skirt_lift_swd3e2 (1).jpg\n",
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\3\\yande.re_1148109_aegir_(azur_lane)_asian_clothes_azur_lane_garter_belt_horns_no_bra_stockings_thighhighs_z_shitei_ero.jpg\n",
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\3\\yande.re_1151692_asian_clothes_azur_lane_cleavage_formidable_(azur_lane)_manjuu_(azur_lane)_no_bra_see_through_swd3e2_thighhighs_unicorn_(azur_lane) (1).jpg\n",
      "C:\\Users\\admin\\Desktop\\qtwork\\123\\3\\yande.re_1161410_gomashio_ponz_thighhighs (1).jpg\n"
     ]
    }
   ],
   "source": [
    "cwd = Path(r'C:\\Users\\admin\\Desktop\\qtwork\\123')\n",
    "df_data = pd.DataFrame()\n",
    "for img_path in cwd.rglob('*.jpg'):\n",
    "    print(str(img_path ))\n",
    "    df = process_image(str(img_path ))\n",
    "    if df.shape[0] > 2:\n",
    "        df_data = pd.concat([df_data, df])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>area</th>\n",
       "      <th>convex_area</th>\n",
       "      <th>bbox_area</th>\n",
       "      <th>filled_area</th>\n",
       "      <th>major_axis_length</th>\n",
       "      <th>minor_axis_length</th>\n",
       "      <th>moments_hu-0</th>\n",
       "      <th>moments_hu-1</th>\n",
       "      <th>moments_hu-2</th>\n",
       "      <th>moments_hu-3</th>\n",
       "      <th>...</th>\n",
       "      <th>inertia_tensor_eigvals-0</th>\n",
       "      <th>inertia_tensor_eigvals-1</th>\n",
       "      <th>bbox-0</th>\n",
       "      <th>bbox-1</th>\n",
       "      <th>bbox-2</th>\n",
       "      <th>bbox-3</th>\n",
       "      <th>centroid-0</th>\n",
       "      <th>centroid-1</th>\n",
       "      <th>image</th>\n",
       "      <th>label</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>26.0</td>\n",
       "      <td>32.0</td>\n",
       "      <td>48.0</td>\n",
       "      <td>26.0</td>\n",
       "      <td>11.565366</td>\n",
       "      <td>3.178095</td>\n",
       "      <td>0.345812</td>\n",
       "      <td>0.088360</td>\n",
       "      <td>0.010038</td>\n",
       "      <td>0.006397</td>\n",
       "      <td>...</td>\n",
       "      <td>8.359856</td>\n",
       "      <td>0.631268</td>\n",
       "      <td>227</td>\n",
       "      <td>1323</td>\n",
       "      <td>239</td>\n",
       "      <td>1327</td>\n",
       "      <td>231.730769</td>\n",
       "      <td>1324.115385</td>\n",
       "      <td>[[False, False, True, False], [False, True, Tr...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>576.0</td>\n",
       "      <td>2266.0</td>\n",
       "      <td>44776.0</td>\n",
       "      <td>576.0</td>\n",
       "      <td>354.089174</td>\n",
       "      <td>4.465753</td>\n",
       "      <td>13.606672</td>\n",
       "      <td>185.023757</td>\n",
       "      <td>8.723657</td>\n",
       "      <td>8.869168</td>\n",
       "      <td>...</td>\n",
       "      <td>7836.196461</td>\n",
       "      <td>1.246434</td>\n",
       "      <td>341</td>\n",
       "      <td>314</td>\n",
       "      <td>573</td>\n",
       "      <td>507</td>\n",
       "      <td>454.720486</td>\n",
       "      <td>409.942708</td>\n",
       "      <td>[[False, False, False, False, False, False, Fa...</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>6797.0</td>\n",
       "      <td>8667.0</td>\n",
       "      <td>11880.0</td>\n",
       "      <td>7000.0</td>\n",
       "      <td>196.769358</td>\n",
       "      <td>52.063808</td>\n",
       "      <td>0.380948</td>\n",
       "      <td>0.109626</td>\n",
       "      <td>0.004928</td>\n",
       "      <td>0.000782</td>\n",
       "      <td>...</td>\n",
       "      <td>2419.886259</td>\n",
       "      <td>169.415009</td>\n",
       "      <td>349</td>\n",
       "      <td>827</td>\n",
       "      <td>547</td>\n",
       "      <td>887</td>\n",
       "      <td>444.934824</td>\n",
       "      <td>858.067971</td>\n",
       "      <td>[[False, False, False, False, False, False, Fa...</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2465.0</td>\n",
       "      <td>4009.0</td>\n",
       "      <td>8580.0</td>\n",
       "      <td>2805.0</td>\n",
       "      <td>113.036944</td>\n",
       "      <td>42.136371</td>\n",
       "      <td>0.368986</td>\n",
       "      <td>0.077814</td>\n",
       "      <td>0.009745</td>\n",
       "      <td>0.000620</td>\n",
       "      <td>...</td>\n",
       "      <td>798.584424</td>\n",
       "      <td>110.967111</td>\n",
       "      <td>413</td>\n",
       "      <td>442</td>\n",
       "      <td>545</td>\n",
       "      <td>507</td>\n",
       "      <td>476.584178</td>\n",
       "      <td>480.595538</td>\n",
       "      <td>[[False, False, False, False, False, False, Fa...</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>31.0</td>\n",
       "      <td>51.0</td>\n",
       "      <td>220.0</td>\n",
       "      <td>31.0</td>\n",
       "      <td>27.062006</td>\n",
       "      <td>1.677910</td>\n",
       "      <td>1.482193</td>\n",
       "      <td>2.163371</td>\n",
       "      <td>0.025559</td>\n",
       "      <td>0.005825</td>\n",
       "      <td>...</td>\n",
       "      <td>45.772009</td>\n",
       "      <td>0.175961</td>\n",
       "      <td>431</td>\n",
       "      <td>894</td>\n",
       "      <td>453</td>\n",
       "      <td>904</td>\n",
       "      <td>441.161290</td>\n",
       "      <td>898.838710</td>\n",
       "      <td>[[True, False, False, False, False, False, Fal...</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 31 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "     area  convex_area  bbox_area  filled_area  major_axis_length  \\\n",
       "0    26.0         32.0       48.0         26.0          11.565366   \n",
       "1   576.0       2266.0    44776.0        576.0         354.089174   \n",
       "2  6797.0       8667.0    11880.0       7000.0         196.769358   \n",
       "3  2465.0       4009.0     8580.0       2805.0         113.036944   \n",
       "4    31.0         51.0      220.0         31.0          27.062006   \n",
       "\n",
       "   minor_axis_length  moments_hu-0  moments_hu-1  moments_hu-2  moments_hu-3  \\\n",
       "0           3.178095      0.345812      0.088360      0.010038      0.006397   \n",
       "1           4.465753     13.606672    185.023757      8.723657      8.869168   \n",
       "2          52.063808      0.380948      0.109626      0.004928      0.000782   \n",
       "3          42.136371      0.368986      0.077814      0.009745      0.000620   \n",
       "4           1.677910      1.482193      2.163371      0.025559      0.005825   \n",
       "\n",
       "   ...  inertia_tensor_eigvals-0  inertia_tensor_eigvals-1  bbox-0  bbox-1  \\\n",
       "0  ...                  8.359856                  0.631268     227    1323   \n",
       "1  ...               7836.196461                  1.246434     341     314   \n",
       "2  ...               2419.886259                169.415009     349     827   \n",
       "3  ...                798.584424                110.967111     413     442   \n",
       "4  ...                 45.772009                  0.175961     431     894   \n",
       "\n",
       "   bbox-2  bbox-3  centroid-0   centroid-1  \\\n",
       "0     239    1327  231.730769  1324.115385   \n",
       "1     573     507  454.720486   409.942708   \n",
       "2     547     887  444.934824   858.067971   \n",
       "3     545     507  476.584178   480.595538   \n",
       "4     453     904  441.161290   898.838710   \n",
       "\n",
       "                                               image  label  \n",
       "0  [[False, False, True, False], [False, True, Tr...      1  \n",
       "1  [[False, False, False, False, False, False, Fa...      2  \n",
       "2  [[False, False, False, False, False, False, Fa...      3  \n",
       "3  [[False, False, False, False, False, False, Fa...      4  \n",
       "4  [[True, False, False, False, False, False, Fal...      5  \n",
       "\n",
       "[5 rows x 31 columns]"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3005, 31)"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_data.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "scaler = StandardScaler()\n",
    "from sklearn.neighbors import LocalOutlierFactor\n",
    "clf = LocalOutlierFactor(n_neighbors=20)\n",
    "\n",
    "X = df_data.loc[:,'area':'inertia_tensor_eigvals-1'].to_numpy()\n",
    "\n",
    "stand_X = scaler.fit_transform(X)\n",
    "\n",
    "y_pred = clf.fit_predict(stand_X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['scaler.pkl']"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import joblib\n",
    "joblib.dump(clf, 'clf.pkl')\n",
    "joblib.dump(scaler, 'scaler.pkl')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def run():\n",
    "    i = 1\n",
    "    for i in range(10):\n",
    "        yield i\n",
    "        i += 1\n",
    "    yield 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "8\n",
      "9\n",
      "0\n"
     ]
    }
   ],
   "source": [
    "gen = run()\n",
    "for value in gen:\n",
    "    print(value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 用于测量粉末颗粒的尺寸和形状\n",
    "\n",
    "from skimage import io, filters, measure, segmentation, morphology, color\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd\n",
    "import joblib\n",
    "from pathlib2 import Path\n",
    "import warnings\n",
    "\n",
    "# 忽略警告\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "# 测量参数名称\n",
    "region_props = ['area', 'convex_area', 'bbox_area', 'filled_area', 'major_axis_length', 'minor_axis_length', 'moments_hu',\n",
    "                'eccentricity', 'equivalent_diameter', 'extent', 'feret_diameter_max', 'perimeter', 'solidity', 'perimeter_crofton',\n",
    "                'orientation', 'inertia_tensor_eigvals', 'bbox', 'centroid', 'image', 'label']\n",
    "\n",
    "stand = joblib.load('stand.pkl')\n",
    "model = joblib.load('model.pkl')\n",
    "\n",
    "class PowderMeasurement:\n",
    "    def __init__(self, file_path, scale=1, bins=10):\n",
    "        self.file_path = file_path\n",
    "        self.scale = scale\n",
    "        self.bins = bins\n",
    "    \n",
    "    def run(self):\n",
    "        cwd = Path(self.file_path)\n",
    "        image_files = cwd.glob('*.jpg')\n",
    "        df_data = pd.DataFrame()\n",
    "        i = 1\n",
    "        for image_file in image_files:\n",
    "            if 'FG' not in str(image_file):\n",
    "                df = self.process_image(image_file)\n",
    "                if df.shape[0] > 2:\n",
    "                    df_data = pd.concat([df_data, df])\n",
    "\n",
    "            yield i\n",
    "            i += 1\n",
    "        data_name = self.file_path + '\\\\data.csv'\n",
    "        df_data.to_csv(data_name, index=False)\n",
    "        \n",
    "        # 统计结果\n",
    "        df_stat = self.statistics(df_data, self.scale,self.bins)\n",
    "        stat_name = self.file_path + '\\\\stat.csv'\n",
    "        df_stat.to_csv(stat_name, index=False)\n",
    "\n",
    "        yield 99\n",
    "    \n",
    "    # 处理 图像\n",
    "    def process_image(image_path):\n",
    "        # 读取图像\n",
    "        image = io.imread(image_path)\n",
    "        \n",
    "        # 转换为灰度图像\n",
    "        gray = color.rgb2gray(image)\n",
    "        \n",
    "        # 二值化\n",
    "        bw = gray < (80/255)\n",
    "        bw = morphology.remove_small_objects(bw, min_size=25)\n",
    "        bw = segmentation.clear_border(bw)\n",
    "        image_new = bw.copy()\n",
    "\n",
    "        bw_label = measure.label(bw)\n",
    "        regions = measure.regionprops_table(bw_label, properties=region_props)\n",
    "        df = pd.DataFrame(regions)\n",
    "\n",
    "        # 机器学习筛选\n",
    "        X = df.loc[:, 'area':'inertia_tensor_eigvals-1'].to_numpy()\n",
    "        X_trans = stand.transform(X)\n",
    "        y_pred = model.predict(X_trans)\n",
    "        df['pred'] = y_pred\n",
    "\n",
    "        image_new_name = image_path.split('.')[0] + '_new.png'\n",
    "        io.imsave(image_new_name, image_new)\n",
    "\n",
    "        # sobel 筛选\n",
    "        sobel = filters.sobel(gray)\n",
    "        for index, row in df.iterrows():\n",
    "            xmin, ymin, xmax, ymax = row['bbox-0':'bbox-3']\n",
    "            region = sobel[ymin:ymax, xmin:xmax].max()\n",
    "            df.loc[index, 'sobel'] = region\n",
    "            if (row['pred'] == 1) and (region < 10):\n",
    "                image_new[bw_label == index + 1] = False\n",
    "                df.loc[index, 'remove'] = True\n",
    "            else:\n",
    "                df.loc[index, 'remove'] = False\n",
    "\n",
    "        # 二值化图像转换并保存\n",
    "        image_new = image_new.astype(np.uint8)\n",
    "        io.imsave(image_new_name, image_new)\n",
    "        \n",
    "        return df\n",
    "\n",
    "    # 统计结果和分级\n",
    "    def statistics(self, df, scale, bin_step:int):\n",
    "        area = df['area'].to_numpy()\n",
    "        dia = np.sqrt(4 * area / np.pi) * scale\n",
    "        if bin_step == 10:\n",
    "            dia_bin = np.array([0, 10, 20, 30, 40, 50, 60, 70, 75, 80, 90, 100, 110, 120])\n",
    "        else:\n",
    "            dia_low = np.min(dia) // bin_step * bin_step\n",
    "            dia_high = np.max(dia) // bin_step * bin_step + bin_step\n",
    "            dia_bin = np.arange(dia_low, dia_high, bin_step)\n",
    "            \n",
    "        hist, _ = np.histogram(dia, bins=dia_bin)\n",
    "        hist = np.round(hist / len(dia), 2)\n",
    "        df = pd.DataFrame({'dia': dia_bin, 'count': hist})\n",
    "        # 计算统计值\n",
    "        # 超过120的百分比，保留 两位小数\n",
    "        over_120 = np.round(np.sum(dia >= 120) / len(dia) *100, 2)\n",
    "        df = df.append({'dia': 120, 'count': over_120}, ignore_index=True)\n",
    "        # 0-75的百分比，保留 两位小数\n",
    "        under_75 = np.round(np.sum(dia < 75) / len(dia) *100, 2)\n",
    "        df = df.append({'dia': 75, 'count': under_75}, ignore_index=True)\n",
    "        # 平均值\n",
    "        mean = np.round(np.mean(dia), 2)\n",
    "        df = df.append({'dia': 'mean', 'count': mean}, ignore_index=True)\n",
    "        # 最大值\n",
    "        max_dia = np.round(np.max(dia), 2)\n",
    "        df = df.append({'dia': 'max', 'count': max_dia}, ignore_index=True)\n",
    "        # 最小值\n",
    "        min_dia = np.round(np.min(dia), 2)\n",
    "        df = df.append({'dia': 'min', 'count': min_dia}, ignore_index=True)\n",
    "\n",
    "        return df\n",
    "\n",
    "    def read_images(self,file_path, scale, bin_step):\n",
    "        # 读取文件夹中的所有图像\n",
    "        cwd = Path(file_path)\n",
    "        image_files = cwd.rglob('*.jpg')\n",
    "        df_data = pd.DataFrame()\n",
    "        for image_file in image_files:\n",
    "            if 'FG' not in str(image_file):\n",
    "                df = self.process_image(image_file)\n",
    "                if df.shape[0] > 2:\n",
    "                    df_data = pd.concat([df_data, df])\n",
    "        data_name = file_path + '\\\\data.csv'\n",
    "        df_data.to_csv(data_name, index=False)\n",
    "        \n",
    "        # 统计结果\n",
    "        df_stat = self.statistics(df_data, scale, bin_step)\n",
    "        stat_name = file_path + '\\\\stat.csv'\n",
    "        df_stat.to_csv(stat_name, index=False)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "pd = PowderMeasurement(file_path=r'C:\\Users\\admin\\Desktop\\qtwork\\123', scale=1, bins=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'PowderMeasurement' object has no attribute 'DataFrame'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[5], line 2\u001b[0m\n\u001b[0;32m      1\u001b[0m gen \u001b[38;5;241m=\u001b[39m pd\u001b[38;5;241m.\u001b[39mrun()\n\u001b[1;32m----> 2\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m gen:\n\u001b[0;32m      3\u001b[0m     \u001b[38;5;28mprint\u001b[39m(i)\n",
      "Cell \u001b[1;32mIn[1], line 31\u001b[0m, in \u001b[0;36mPowderMeasurement.run\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m     29\u001b[0m cwd \u001b[38;5;241m=\u001b[39m Path(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfile_path)\n\u001b[0;32m     30\u001b[0m image_files \u001b[38;5;241m=\u001b[39m cwd\u001b[38;5;241m.\u001b[39mglob(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m*.jpg\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m---> 31\u001b[0m df_data \u001b[38;5;241m=\u001b[39m \u001b[43mpd\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mDataFrame\u001b[49m()\n\u001b[0;32m     32\u001b[0m i \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[0;32m     33\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m image_file \u001b[38;5;129;01min\u001b[39;00m image_files:\n",
      "\u001b[1;31mAttributeError\u001b[0m: 'PowderMeasurement' object has no attribute 'DataFrame'"
     ]
    }
   ],
   "source": [
    "gen = pd.run()\n",
    "for i in gen:\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\admin\\AppData\\Local\\Temp\\ipykernel_38880\\437156181.py:6: DeprecationWarning: sipPyTypeDict() is deprecated, the extension module should use sipPyTypeDictRef() instead\n",
      "  class PandasModel(QAbstractTableModel):\n"
     ]
    },
    {
     "ename": "SystemExit",
     "evalue": "0",
     "output_type": "error",
     "traceback": [
      "An exception has occurred, use %tb to see the full traceback.\n",
      "\u001b[1;31mSystemExit\u001b[0m\u001b[1;31m:\u001b[0m 0\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\admin\\.conda\\envs\\dl\\lib\\site-packages\\IPython\\core\\interactiveshell.py:3468: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.\n",
      "  warn(\"To exit: use 'exit', 'quit', or Ctrl-D.\", stacklevel=1)\n"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "import pandas as pd\n",
    "from PyQt5.QtWidgets import QApplication, QMainWindow, QTableView\n",
    "from PyQt5.QtCore import QAbstractTableModel, Qt\n",
    "\n",
    "class PandasModel(QAbstractTableModel):\n",
    "    def __init__(self, data):\n",
    "        QAbstractTableModel.__init__(self)\n",
    "        self._data = data\n",
    "\n",
    "    def rowCount(self, parent=None):\n",
    "        return self._data.shape[0]\n",
    "\n",
    "    def columnCount(self, parent=None):\n",
    "        return self._data.shape[1]\n",
    "\n",
    "    def data(self, index, role=Qt.DisplayRole):\n",
    "        if index.isValid() and role == Qt.DisplayRole:\n",
    "            return str(self._data.iloc[index.row(), index.column()])\n",
    "        return None\n",
    "\n",
    "    def headerData(self, section, orientation, role):\n",
    "        if role == Qt.DisplayRole:\n",
    "            if orientation == Qt.Horizontal:\n",
    "                return str(self._data.columns[section])\n",
    "            else:\n",
    "                return str(section)\n",
    "        return None\n",
    "\n",
    "# 创建一个简单的DataFrame\n",
    "data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}\n",
    "df = pd.DataFrame(data)\n",
    "\n",
    "# 创建应用程序和主窗口\n",
    "app = QApplication(sys.argv)\n",
    "main_window = QMainWindow()\n",
    "\n",
    "# 创建QTableView\n",
    "table_view = QTableView()\n",
    "model = PandasModel(df)\n",
    "table_view.setModel(model)\n",
    "\n",
    "# 将table_view设置为中央小部件\n",
    "main_window.setCentralWidget(table_view)\n",
    "main_window.show()\n",
    "\n",
    "# 运行应用程序\n",
    "sys.exit(app.exec_())\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "dl",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
